package com.pension.servlet.calendar;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;

import org.json.simple.JSONObject;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
import com.pension.model.dao.MemberDao;
import com.pension.model.dao.ReservationDao;
import com.pension.model.dao.RoomDao;
import com.pension.model.dao.RoomoptionDao;
import com.pension.model.dto.Member;
import com.pension.model.dto.Reservation;
import com.pension.model.dto.Room;
import com.pension.model.dto.Roomoption;

@WebServlet("/calendar/calendars.action")
public class Calendars extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	public final static String ADMIN = "admin";
	public final static String MEMBER = "member";
	public final static String USER = Calendars.MEMBER;
	public final static String GUEST = "guest";
	public final static boolean YES = true;
	public final static boolean NO = false;
	
	public final static String ACCESS = "calendar_access";
	public final static String ROOMSLIST = "calendar_roomslist";
	public final static String ADMINMOD = "calendar_adminmod";
	public final static String REMOTE_ID = "calendar_remoteid"; 
	
	public final static String CALENDARS_JPATH = "/WEB-INF/views/calendar/";
	public final static String CALENDARS_JSP = Calendars.CALENDARS_JPATH + "calendars.jsp";
	
	public final static String CALENDARS_APATH = "/pension/calendar/";
	public final static String CALENDARS_ACTION = Calendars.CALENDARS_APATH + "calendars.action";
	
	public final static String TASK_RESERVATION_SYSTEM = "task_reservation_system";
	public final static String TASK_ADMIN_MOD_JSP = "task_admin_mod_jsp";
	
	public static void sendMessage(String key, String var, String documentID)
	{
		System.out.println(" Calendars에서 진짜 날린다~ " + key + " " + var + " " + documentID);
	}
	
	/*
	private static int SEQUENCE = 0;
	
	private String accessFix = "";
	
	public Calendar sequenceInit()
	{
		SEQUENCE = 0;
		
		return this;
	}
	
	public Calendar view()
	{
		System.out.println("Calendar the view! " + this);
		
		return this;
	}
	
	public static String soAccess(String accstr)
	{
		StringBuilder str = new StringBuilder(256);
		
		if ( SEQUENCE == 0 )
		{
			str.append("?");
		}
		else
		{
			str.append("&");
		}
		
		str.append("access=");
		str.append(accstr);
		
		++SEQUENCE;
		return str.toString();
	}
	
	public static String soRoomsArray(int[] list)
	{
		ArrayList<Integer> temp = new ArrayList<Integer>();
		
		for (Integer e : list)
		{
			temp.add(e);
		}
		
		return soRoomsArray(temp);
	}
	
	public static String soRoomsArray(ArrayList<Integer> list)
	{
		StringBuilder str = new StringBuilder(256);
		
		if ( SEQUENCE == 0 )
		{
			str.append("?");
		}
		else
		{
			str.append("&");
		}
		
		str.append("roomsarray=");
		str.append(list.toString());
		
		++SEQUENCE;
		return str.toString();
	}
	*/
	
	@SuppressWarnings({ "unchecked", "deprecation" })
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		//System.out.printf("in a Calendar servlet..");
		
		String task = (String) req.getParameter("task");
		
		if ( task != null )
		{
			if ( !task.isEmpty() )
			{
				// 1차 인증하기 (보안관련, 구현 요망)
				
				// 비동기 정보 요청 회답
				if ( task.equals(Calendars.TASK_RESERVATION_SYSTEM))
				{
					// 데이터 받아오기
					String temp1 = (String)req.getParameter("year");
					String temp2 = (String)req.getParameter("month");
					String temp3 = (String)req.getParameter("date_min");
					String temp4 = (String)req.getParameter("date_max");
					
					/*
					//System.out.print("\r\n");
					String[] temp3_s = temp3.split("-");
					String[] temp4_s = temp4.split("-");
					//for (String s : temp3_s) System.out.println("원본 : " + s);
					
					if ( temp3_s[0].substring(0, 1).equals("0") )
						temp3_s[0] = temp3_s[0].substring(1, temp3_s[0].length());
					
					if ( temp3_s[1].substring(0, 1).equals("0") )
						temp3_s[1] = temp3_s[1].substring(1, temp3_s[1].length());
					
					if ( temp3_s[2].substring(0, 1).equals("0") )
						temp3_s[2] = temp3_s[2].substring(1, temp3_s[2].length());
					
					if ( temp4_s[0].substring(0, 1).equals("0") )
						temp4_s[0] = temp4_s[0].substring(1, temp4_s[0].length());
					
					if ( temp4_s[1].substring(0, 1).equals("0") )
						temp4_s[1] = temp4_s[1].substring(1, temp4_s[1].length());
					
					if ( temp4_s[2].substring(0, 1).equals("0") )
						temp4_s[2] = temp4_s[2].substring(1, temp4_s[2].length());
					
					//for (String s : temp3_s) System.out.println("수정 : " + s);
					
					int temp3_s1_int = Integer.parseInt(temp3_s[0]);
					int temp3_s2_int = Integer.parseInt(temp3_s[1]);
					int temp3_s3_int = Integer.parseInt(temp3_s[2]);
					
					int temp4_s1_int = Integer.parseInt(temp4_s[0]);
					int temp4_s2_int = Integer.parseInt(temp4_s[1]);
					int temp4_s3_int = Integer.parseInt(temp4_s[2]);
					
					//System.out.println("결론은? : " + temp3_s1_int + "-" + temp3_s2_int + "-" + temp3_s3_int);
					
					Date date_min_obj = new Date(temp3_s1_int, temp3_s2_int, temp3_s3_int);
					Date date_max_obj = new Date(temp4_s1_int, temp4_s2_int, temp4_s3_int);
					
					//System.out.println("됨? min : " + date_min_obj.toLocaleString());
					*/
					
					// 2차 인증하기 (보안관련, 구현 요망)
					
					
					// 데이터 기반 DB 조회하기
					RoomDao roomDao = new RoomDao();
					ReservationDao reservationDao = new ReservationDao();
					RoomoptionDao roomoptionDao = new RoomoptionDao();
					
					List<Room> rooms = roomDao.getRooms();
					List<Roomoption> options = roomoptionDao.getRoomsoptionList();
					//List<Reservation> reservations = reservationDao.getSuitableDateList(date_min_obj, date_max_obj);
					List<Reservation> reservations = reservationDao.getSuitableDateList(temp3, temp4);
					
					//System.out.println("예약 정보를 불러옵니다.. " + reservations);
					
					for(Reservation r : reservations)
					{
						//System.out.println("조건에 맞는 예약 검색! : " + r.getStartdate().toLocaleString() + "  " + r.getDays() + "박 예약함" );
					}
					
					// 데이터 보내기
					JSONObject json = new JSONObject();

					ObjectMapper mapper = new ObjectMapper();
					
					String json_backdata_rooms = mapper.writeValueAsString(rooms);
					String json_backdata_options = mapper.writeValueAsString(options);
					String json_backdata_reservations = mapper.writeValueAsString(reservations);
					
					json.put("rooms", json_backdata_rooms);
					json.put("options", json_backdata_options);
					json.put("reservations", json_backdata_reservations);
					
					//Room roomtest = mapper.readValue(json_backdata_rooms, Room.class);
					//System.out.println( roomtest.toString() );
					
					resp.setContentType("text/html;charset=utf-8");
					resp.setHeader("Cache-Control", "no-cache");
					resp.getWriter().write(json.toJSONString());
					
					// 서블릿을 종료
					this.destroy();
					return;
				}
				// 우왕 신나는 막코딩 ㅜㅜ
				else if ( task.equals("merber_test") )
				{
					HttpSession session = req.getSession();
					Member m = (Member)session.getAttribute("loginuser");
					
					if ( m != null )
					{
						if ( m.getMemberId() != null )
						{
							String dumim = "d39bf2737de75fe87250bb8788037b24e8fd54a1efe0ecf4d961e699edc2b8188c5805b0d9ab1441057fe7cdcc655a1a3059d946fed8b0181a05e6461af35e2b7a029ba2521d0e56d8f889db016d1840";
							resp.setContentType("text/html;charset=utf-8");
							resp.setHeader("Cache-Control", "no-cache");
							resp.getWriter().write(dumim);
						}
					}
					
					this.destroy();
					return;
				}
				// 이건 더 심한 막코딩 ㅜㅜ
				else if ( task.equals("join") )
				{
					//location.replace("/pension/calendar/calendars.action?task=join&room=" + t[0].getValue() + "&op1=" + op1+ "&op2=" + op2+ "&op3=" + op3 + "&start=" + this.save_date1 + "&end=" + this.save_date2 + "&idx1=" + this.save_idx1 + "&idx2=" + this.save_idx2 + "&days=" + this.save_day + "&start_time=" + this.save_time );
					
					String room = req.getParameter("room");
					String op1 = req.getParameter("op1");
					String op2 = req.getParameter("op2");
					String op3 = req.getParameter("op3");
					String start = req.getParameter("start");
					String end = req.getParameter("end");
					String idx1 = req.getParameter("idx1");
					String idx2 = req.getParameter("idx2");
					String day = req.getParameter("days");
					String start_time = req.getParameter("start_time");
					
					ReservationDao dao_reser = new ReservationDao();
					RoomoptionDao dao_op = new RoomoptionDao();
					RoomDao dao_room = new RoomDao();
					Reservation reser = new Reservation();
					
					List<Roomoption> ops = new ArrayList<Roomoption>();
					
					int money = 0;
					
					if ( op1.equals("1") )
					{
						Roomoption r = dao_op.getRoomsoptionByNumber(1);
						System.out.println("테1 : " + r);
						ops.add(r);
						money += r.getPriceoption();
					}
					if ( op2.equals("1") ) 
					{
						Roomoption r = dao_op.getRoomsoptionByNumber(2);
						System.out.println("테2 : " + r);
						ops.add(r);
						money += r.getPriceoption();
					}
					if ( op3.equals("1") ) 
					{
						Roomoption r = dao_op.getRoomsoptionByNumber(3);
						System.out.println("테3 : " + r);
						ops.add(r);
						money += r.getPriceoption();
					}
					
					HttpSession session = req.getSession();
					Member m = (Member)session.getAttribute("loginuser");
					
					if ( m == null )
					{
						// 서블릿을 종료
						//this.destroy();
						//return;
					}
					else
					{
						money += (dao_room.getRoomByRoomNumber(Integer.valueOf(room)).getPriceRoom()) * Integer.valueOf(day);
						
						System.out.println("최종 가격 : " + money + " 옵션 갯수 : " + ops.size());
						
						reser.setOptions(ops);
						reser.setDays(Integer.valueOf(day));
						reser.setPricetotal(money);
						reser.setDeletedroom(NO);
						reser.setUsepeople(2);
						reser.setRoomnumber(Integer.valueOf(room));
						reser.setRoomsstatus(1);
						reser.setMemberid(m.getMemberId());
						reser.setStartdate(new Date(Long.valueOf(start_time)));
						
						dao_reser.insertReservation(reser);
						
						//HttpSession session = req.getSession();
						//session.setAttribute("loginuser", member);
						
						// 서블릿을 종료
						//this.destroy();
						//return;
					}
				}
				else
				{
					
				}
			}
			else
			{
				
			}
		}
		
		//System.out.printf("ok!\r\n");
		
//		Enumeration<String> enum_01 = req.getAttributeNames();
//		
//		if ( enum_01 != null )
//		{
//			//System.out.println(" enum_01 : " + enum_01 );
//			
//			while(enum_01.hasMoreElements())
//			{
//				//String key = enum_01.nextElement().toString();
//				//String var = (String) req.getAttribute(key);
//	
//				//System.out.println(key + " key var = " + var);
//			}
//		}
		
		
		/*
		PrintWriter writer = resp.getWriter();
		writer.println("<br /> test : " + test);
		*/
		
		
		/*
		switch (access)
		{
			case Calendar.ADMIN :
				if ( loginuser == null )
				{
					this.destroy();
					return;
				}
				
				if ( loginuser.getUserType() != "admin" )
				{
					this.destroy();
					return;
				}
				
				// 접근 허용, 보안 취약점은 있긴 있지만.. 일단.
				accessFix = Calendar.ADMIN;
			break;
			
			case Calendar.USER :
				if ( loginuser == null )
				{
					this.destroy();
					return;
				}
				
				accessFix = Calendar.USER;
				
			break;
			
			case Calendar.GUEST :
				
				accessFix = Calendar.GUEST;
			break;
		
			default :
				this.destroy();
				return;
		}
		*/
		
		
		// 조회
		
		/*
		RequestDispatcher dispatcher = 
			request.getRequestDispatcher("/WEB-INF/views/account/loginform.jsp");

		dispatcher.forward(request, response);
		*/
		
        /*
		RequestDispatcher dispatcher = 
				req.getRequestDispatcher("/WEB-INF/views/calendar/calendar.jsp");
		

		dispatcher.forward(req, resp);
		*/
		
		req.setAttribute(Calendars.ADMINMOD, Calendars.YES);
		
		RequestDispatcher dispatcher1 = 
				req.getRequestDispatcher(Calendars.CALENDARS_JSP);
		
		
		dispatcher1.forward(req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		
		//System.out.printf("post ");
		doGet(req, resp);
	}
	
}
